package ai.people.platform.information.context;

import ai.people.core.information.api.InformationStanderSearchService;
import ai.people.core.plugin.annotation.HotRefresh;
import ai.people.netmon.framework.exception.enums.CommonEnum;
import ai.people.netmon.framework.exception.enums.InformationSearchExceptionEnum;
import ai.people.netmon.framework.exception.type.BusinessException;
import ai.people.platform.information.properties.DataSourceProperties;
import ai.people.platform.information.properties.InformationServerDataSources;
import ai.people.platform.information.service.impl.InformationStanderSearchServiceImpl;
import com.google.common.collect.Maps;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据服务上下文
 *
 * @author LiGuanNan
 * @date 2022/6/14 14:32
 */
@Slf4j
@Data
@HotRefresh
@Component("informationServiceContext")
public class InformationServiceContext {

    @Autowired
    public InformationServerDataSources informationServerDataSources;

    /**
     * 数据服务map集合
     */
    public volatile Map<String, InformationStanderSearchService> thirdPartyInformationSearchServiceMap = Maps.newConcurrentMap();

    @PostConstruct
    public void init(){
        //检查配置信息
        this.checkServerConfig().forEach(config->{
            thirdPartyInformationSearchServiceMap.put(config.getName(), new InformationStanderSearchServiceImpl(config));
        });
    }

    /**
     * 当有数据源配置更新时，刷新服务上下文
     */
    public void refresh(){
        Map<String, InformationStanderSearchService> newMaps = Maps.newConcurrentMap();
        //检查配置信息
        this.checkServerConfig().forEach(config->{
            newMaps.put(config.getName(), new InformationStanderSearchServiceImpl(config));
        });
        thirdPartyInformationSearchServiceMap = newMaps;
        log.warn("刷新信息查询第三方服务上下文, done");
    }

    /**
     * 检查数据服务配置
     */
    public List<DataSourceProperties> checkServerConfig() {
        if(informationServerDataSources == null || CollectionUtils.isEmpty(informationServerDataSources.getDatasource())){
            throw new BusinessException(CommonEnum.CONFIGURATION_ERROR);
        }
        //处理已被删除了的第三方配置
        thirdPartyInformationSearchServiceMap.keySet().forEach(key->{
            if(informationServerDataSources.getDatasource().stream().noneMatch(o->Objects.equals(o.getName(), key))){
                thirdPartyInformationSearchServiceMap.remove(key);
            }
        });
        return getEnableServerConfigList();
    }

    /**
     * 获得搜索服务信息来源
     *
     * @param source 源
     * @return {@link InformationStanderSearchService}
     */
    public InformationStanderSearchService getThirdPartyInformationSearchServiceBySource(String source){
        Optional<DataSourceProperties> first = informationServerDataSources.getDatasource().stream().filter(o -> Objects.equals(o.getName(), source)).findFirst();
        if(first.isPresent()){
            return getThirdPartyInformationSearchService(first.get());
        }
        log.error("非法的数据源类型，source：【{}】", source);
        throw new BusinessException(InformationSearchExceptionEnum.ILLEGAL_DATA_SOURCE);
    }

    /**
     * 获取可用服务配置列表
     *
     * @return {@link List}<{@link DataSourceProperties}>
     */
    public List<DataSourceProperties> getEnableServerConfigList() {
        return informationServerDataSources.getDatasource().stream().filter(DataSourceProperties::isEnable).collect(Collectors.toList());
    }

    /**
     * 获取指定服务配置
     *
     * @return {@link List}<{@link DataSourceProperties}>
     */
    public DataSourceProperties getEnableServerConfig(String name) {
        List<DataSourceProperties> collect = informationServerDataSources.getDatasource().stream().filter(o -> o.isEnable() && o.getName().equalsIgnoreCase(name)).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(collect)){
            return null;
        }
        return collect.get(0);
    }

    /**
     * 获得信息搜索服务
     *
     * @param config 配置
     * @return {@link InformationStanderSearchService}
     */
    public InformationStanderSearchService getThirdPartyInformationSearchService(DataSourceProperties config) {
        if(config != null){
            InformationStanderSearchService service = thirdPartyInformationSearchServiceMap.get(config.getName());
            if(service == null){
                service = new InformationStanderSearchServiceImpl(config);
                thirdPartyInformationSearchServiceMap.put(config.getName(), service);
            }
            return service;
        }
        return null;
    }

    /**
     * 得到搜索进度的redis key（hash结构）
     *
     * @param sid sid
     * @return {@link String}
     */
    public String getSearchProgressKey(long sid) {
        return "information::search::progress::" + sid;
    }

    /**
     * 得到搜索结果的redis key（hash结构）
     *
     * @param sid sid
     * @return {@link String}
     */
    public String getSearchResultKey(long sid) {
        return "information::search::result::" + sid;
    }

}
